<template>
  <view class="_tab-box" :style="{fontSize: defaultConfig.fontSize + 'rpx', color: defaultConfig.color}">
    <scroll-view
      id="_scroll"
      :scroll-x="true"
      class="scroll-view-h"
      scroll-with-animation
      :scroll-left="slider.scrollLeft"
    >
      <view class="_scroll-content">
        <view class="_tab-item-box" :class="[defaultConfig.itemWidth ? '_clamp' : '_flex']">
          <block v-for="(item, index) in tabList" :key="index">
            <view
              :id="'_tab_'+index"
              class="_item"
              :class="{ '_active': tagIndex === index }"
              :style="{color: tagIndex == index ? defaultConfig.activeColor : defaultConfig.color, 'width': defaultConfig.itemWidth ? defaultConfig.itemWidth + 'rpx' : ''}"
              @click="tabClick(index)"
            >{{ item[defaultConfig.key] || item }}</view>
          </block>
        </view>
        <view
          class="_underline"
          :style="{
            transform: 'translateX(' + slider.left + 'px)',
            width: slider.width + 'px',
            height: defaultConfig.underLineHeight + 'rpx',
            backgroundColor: defaultConfig.underLineColor,
          }"
        ></view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  name: 'LiuyunoTabs',
  props: {
    tabData: {
      type: Array,
      default: () => []
    },
    activeIndex: {
      type: Number,
      default: 0
    },
    config: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      tabList: [],
      tagIndex: 0,
      slider: {
        left: 0,
        width: 0,
        scrollLeft: 0
      },
      scorll: {},
      defaultConfig: {
        // 要显示的key
        key: 'name',
        // 字体大小 rpx
        fontSize: 30,
        // 字体颜色
        color: '#313131',
        // 激活字体颜色
        activeColor: '#e54d42',
        // item宽度 0为自动
        itemWidth: 0,
        // 下划线左右边距，文字宽度加边距 rpx
        underLinePadding: 10,
        // 下划线宽度 rpx  注意：设置了此值 underLinePadding 失效
        underLineWidth: 0,
        // 下划线高度 rpx
        underLineHeight: 5,
        // 下划线颜色
        underLineColor: '#e54d42'
      }
    };
  },
  watch: {
    tabData(value) {
      this.updateData();
      setTimeout(() => {
        this.updateTabWidth();
      }, 0);
    },
    config(value) {
      this.updateConfig();
    },
    activeIndex(value) {
      this.tagIndex = value;
    }
  },
  mounted() {
    this.updateConfig();
    this.updateData();
    this.tagIndex = this.activeIndex;

    this.$nextTick(() => {
      this.calcScrollPosition();
    });
  },
  methods: {
    updateData() {
      let data = [];
      if (typeof (this.tabData[0]) === 'string') {
        this.tabData.forEach((item, index) => {
          data.push({
            name: item
          });
        });
        this.defaultConfig.key = 'name';
      } else {
        data = JSON.parse(JSON.stringify(this.tabData));
      }

      this.tabList = data;
    },
    updateConfig() {
      this.defaultConfig = Object.assign(this.defaultConfig, this.config);
    },
    calcScrollPosition() {
      const query = uni.createSelectorQuery().in(this);

      query.select('#_scroll').boundingClientRect((res) => {
        this.scorll = res;
        this.updateTabWidth();
      }).exec();
    },
    updateTabWidth(index = 0) {
      const data = this.tabList;

      if (data.length == 0) return false;

      const query = uni.createSelectorQuery().in(this);

      query.select('#_tab_' + index).boundingClientRect((res) => {
        data[index]._slider = {
          width: res.width,
          left: res.left,
          scrollLeft: res.left - (data[index - 1] ? data[index - 1]._slider.width : 0)
        };

        if (this.tagIndex == index) {
          this.tabToIndex(this.tagIndex);
        }

        index++;
        if (data.length > index) {
          this.updateTabWidth(index);
        }
      }).exec();
    },

    tabToIndex(index) {
      const _slider = this.tabList[index]._slider;

      let width = uni.upx2px(this.defaultConfig.underLineWidth);

      if (!width) {
        if (this.defaultConfig.itemWidth) {
          width = uni.upx2px(this.defaultConfig.itemWidth);
        } else {
          width = this.tabList[index][this.defaultConfig.key].length * uni.upx2px(this.defaultConfig.fontSize);
        }
        width += uni.upx2px(this.defaultConfig.underLinePadding) * 2;
      }

      const scorll_left = this.scorll.left || 0;

      this.slider = {
        left: _slider.left - scorll_left + (_slider.width - width) / 2,
        width: width,
        scrollLeft: _slider.scrollLeft - scorll_left
      };
    },

    tabClick(index) {
      this.tagIndex = index;
      this.tabToIndex(index);
      this.$emit('tabClick', index);
    }
  }
};
</script>

<style lang="scss" scoped>
  ._tab-box {
    position: relative;
    z-index: 10;
    display: flex;
    width: 100%;
    height: 90rpx;
    font-size: 26rpx;
    line-height: 90rpx;

    ::-webkit-scrollbar {
      display: none;
    }

    .scroll-view-h {
      width: 100%;
      height: 100%;
      white-space: nowrap;
      box-sizing: border-box;

      ._scroll-content {
        position: relative;
        width: 100%;
        height: 100%;

        ._tab-item-box {
          height: 100%;

          &._flex {
            display: flex;

            ._item {
              flex: 1;
            }
          }

          &._clamp {
            ._item {
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
            }
          }

          ._item {
            position: relative;
            display: inline-block;
            height: 100%;
            padding: 0 30rpx;
            color: #333;
            text-align: center;
            text-align: center;

            &._active {
              font-weight: bold;
              color: #e54d42;
            }
          }
        }

        ._underline {
          position: absolute;
          bottom: 0;
          height: 4rpx;
          background-color: #e54d42;
          border-radius: 6rpx;
          transition: 0.5s;
        }
      }
    }
  }
</style>
